/*----------------------------------------------------------------------------
Owner(s): Shane Whitfield
$Copyright: $
$Id: $
----------------------------------------------------------------------------*/

#include "go_playerunits.h"
#include "timermgr.h"
#include "gomgr.h"
#include "world.h"
#include "nodemgr.h"

/*--------------------------------------------------------------------------*/
CGoHealStation::CGoHealStation()
{	
	m_foundNewTargets = false;
	m_state = EState_WaitingConstruction;
	m_tState = 0.0f;
	m_healingPing = 0.5f;
	m_healRadius = 1.0f;
	memset(m_healers, 0, sizeof(CGoHealer*)*2);
	
	SetConstructionTime(1.0f);
	SetBoundingRadius(0.2);
	setProvidesConnection(false);
	
	SetTexture("healStation.png");
}

CGoHealStation::~CGoHealStation()
{
	if (m_healers[0])
	{
		delete m_healers[0];
	}
	
	if (m_healers[1])
	{
		delete m_healers[1];
	}
}

void CGoHealStation::createHealers()
{
	Vector2f startPos = GetPos();
	startPos.x += 0.05;
	m_healers[0] = static_cast<CGoHealer*>(g_gomgr.CreateGo(EClass_Healer, startPos));
	m_healers[0]->SetHealingStation(this);
	
	startPos.x -= 0.1;
	m_healers[1] = static_cast<CGoHealer*>( g_gomgr.CreateGo(EClass_Healer, startPos));
	m_healers[1]->SetHealingStation(this);
}

void CGoHealStation::Update()
{
	super::Update();
	
	for(;;)
	{
		EState prevState = m_state;
		switch(m_state)
		{
		case EState_WaitingConstruction:
			{
				if (IsPlaced() && IsConstructed())
				{
					setState(EState_SearchingForTargets);
				}
			}
			break;
		case EState_WaitingHealPing :
			{
				//can we ping again?
				if ((T() - m_tState) >= m_healingPing)
				{
					setState(EState_SearchingForTargets);
				}
			}
			break;
		case EState_AllHealersInUse :
			{
				//if any of the healers don't have a target...
				// then go get a new one for them.
				for(int iHealTarget = 0; iHealTarget < 2; iHealTarget++)
				{
					if (!m_healers[iHealTarget]->GetHealTarget())
					{
						setState(EState_SearchingForTargets);
						break;
					}
				}
			}
			break;
		case EState_SearchingForTargets:
			{
				//if we didn't find any targets...
				if(m_foundNewTargets)
				{
					setState(EState_AllHealersInUse);
				}
				else
				{
					setState(EState_WaitingHealPing);
				}

			}
		}
		
		if (prevState == m_state)
		{
			break;
		}
	}
}

void CGoHealStation::findTargetsForHealers()
{
	m_foundNewTargets = false;
	
	//find all the nodes that need healing
	//$$$$ and prioritize them based off percent health
	std::vector<CGoNode*> possibleTargets;	
	g_gomgr.GetNearNodesNotFullHealth(GetPos(), m_healRadius, possibleTargets);
	
	if(possibleTargets.size() == 0)
	{
		return;
	}
	
	for(int iHealer = 0; iHealer < 2; iHealer++)
	{
		//if the healer doesn't have a target find one
		CGoHealer* healer = m_healers[iHealer];
		if (!healer->GetHealTarget())
		{
			m_foundNewTargets = true;
			healer->SetHealTarget(possibleTargets[0]);
		}
	}
}

void CGoHealStation::setState(EState i_state)
{
	switch(m_state) 
	{
	case EState_WaitingConstruction:
		{
			createHealers();
		}
		break;
		
	}
	
	m_state = i_state;
	m_tState = T();
	
	switch(m_state)
	{
	case EState_SearchingForTargets:
		{
			findTargetsForHealers();
		}
		break;
	}
}


/*--------------------------------------------------------------------------*/
CGoMiningStation::CGoMiningStation()
{	
	m_state = EState_WaitingConstruction;
	m_miningRadius = 1.0f;
	memset(m_miners, 0, sizeof(CGoMiner*)*2);
	
	SetConstructionTime(1.0f);
	SetBoundingRadius(0.2);
	setProvidesConnection(false);
	
	SetTexture("miningStation.png");
    SetDepthLayer(EDepthLayer_GoPlayer);

}

CGoMiningStation::~CGoMiningStation()
{
	if (m_miners[0])
	{
		delete m_miners[0];
	}
	
	if (m_miners[1])
	{
		delete m_miners[1];
	}
}

void CGoMiningStation::createMiners()
{
	Vector2f startPos = GetPos();
	startPos.x += 0.05;
	m_miners[0] = static_cast<CGoMiner*>(g_gomgr.CreateGo(EClass_Miner, startPos));
	m_miners[0]->SetMiningStation(this);
	
	startPos.x -= 0.1;
	m_miners[1] = static_cast<CGoMiner*>( g_gomgr.CreateGo(EClass_Miner, startPos));
	m_miners[1]->SetMiningStation(this);
}

void CGoMiningStation::Update()
{
	super::Update();
	
	for(;;)
	{
		EState prevState = m_state;
		switch(m_state)
		{
		case EState_WaitingConstruction:
			{
				if (IsPlaced() && IsConstructed())
				{
					setState(EState_Mining);
				}
			}
			break;
		}
		
		if (prevState == m_state)
		{
			break;
		}
	}
}

CGoMinerals* CGoMiningStation::GetClosestMiningTarget()
{	
	//find all the nodes that need healing
	//$$$$ and prioritize them to closest
	std::vector<CGoMinerals*> possibleTargets;	
	g_gomgr.GetNearMinerals(GetPos(), m_miningRadius, possibleTargets);
	
	if(possibleTargets.size() == 0)
	{
		return NULL;
	}

	return possibleTargets[0];
}

void CGoMiningStation::setState(EState i_state)
{
	switch(m_state) 
	{
	case EState_WaitingConstruction:
		{
			createMiners();
		}
		break;
		
	}
	
	m_state = i_state;
}



/*--------------------------------------------------------------------------*/
CGoNucleus::CGoNucleus()
{
	setProvidesConnection(true);
	setRequiresConnection(false);
	setConnectionsAllowed(6);

	SetConstructionTime(1.5f);
	SetBoundingRadius(0.3f);
	
	//load the texture of the swarmers
	SetTexture("nucleus.png");
	
	g_nodemgr.RegisterRootNode(this);
 
}

void CGoNucleus::onDeath()
{
	super::onDeath();
	
	g_world.SetLevelFailed();
}

/*--------------------------------------------------------------------------*/
CGoExpansionNode::CGoExpansionNode()
{
	SetConstructionTime(0.5f);
	SetBoundingRadius(0.1f);
	setConnectionsAllowed(6);
	
	SetTexture("expansionnode.png");
}

/*-----------------------------------EOF!-----------------------------------*/ 
